package org.halk;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;

/**
 * 映射所有以 /static/ 开头的 GET 请求
 * @Author haozhu7
 * @Date 2025/11/18 10:52
 **/
@WebServlet("/static/*")
public class StaticResourceServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 1. 获取请求路径中 /static/ 后面的部分（例如：请求 /static/test.html，这里获取 /test.html）
        String pathInfo = request.getPathInfo();
        if (pathInfo == null || pathInfo.equals("/")) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "资源不存在");
            return;
        }

        // 2. 构建静态资源的实际路径（webapp/static 目录下）
        String realPath = getServletContext().getRealPath("/static" + pathInfo);
        File resourceFile = new File(realPath);

        // 3. 校验文件是否存在（防止路径遍历攻击）
        if (!resourceFile.exists() || !resourceFile.isFile()) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "资源不存在");
            return;
        }

        // 4. 设置响应的 Content-Type（根据文件后缀自动识别）
        String contentType = Files.probeContentType(resourceFile.toPath());
        if (contentType != null) {
            response.setContentType(contentType);
        } else {
            response.setContentType("application/octet-stream");  // 默认二进制流
        }

        // 5. 读取文件并写入响应流
        try (InputStream in = new FileInputStream(resourceFile);
             OutputStream out = response.getOutputStream()) {

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
        }
    }
}